package com.sun;
/**
 * https://leetcode.cn/problems/zigzag-conversion/
 *将一个给定字符串 s 根据给定的行数 numRows ，以从上往下、从左到右进行 Z 字形排列。
 */
public class Test6ZConvert {
    public static void main(String[] args) {
        String str = "PAYPALISHIRING";
        //getNum(str,5);
        //String convert = convert1(str, 3);
        String convert = convert4(str, 3);
        System.out.println(convert);
    }

    /**
     *方法一：利用二维矩阵模拟
     */
    public static String convert1(String str, int numRows){
        if(numRows == 1 || str.length() < numRows){
            return str;
        }
       int rnak = getRank(str,numRows);
       char[][] mat = new char[numRows][rnak];
        for (int i = 0, x = 0,y = 0; i < str.length(); i++) {
            mat[x][y]=str.charAt(i);
            if (i % (2 * numRows -2) < numRows -1){
                x++;
            }else {
                x--;
                y++;
            }
        }
        StringBuffer ans = new StringBuffer();
        for (char[] row : mat) {
            for (char ch : row) {
                if (ch != 0) {
                    ans.append(ch);
                }
            }
        }
        return ans.toString();
    }

    /**
     * 方法二：压缩矩阵空间
     * 方法一中的矩阵有大量的空间没有被使用，能否优化呢？
     */
    public static String convert2(String str, int numRows){
        if(numRows == 1 || numRows > str.length()){
            return str;
        }
        StringBuffer[] stringBuffer = new StringBuffer[numRows];
        for (int i = 0; i < stringBuffer.length; i++) {
            stringBuffer[i]=new StringBuffer();
        }
        for (int i = 0, x = 0, m = 2 * numRows -2; i < str.length(); i++) {
            stringBuffer[x].append(str.charAt(i));
            int n = i % m;
            if (n < numRows -1){
                x++;
            }else {
                x--;
            }
        }
        StringBuffer res = new StringBuffer();
        for (StringBuffer buffer : stringBuffer) {
            res.append(buffer);
        }
        return res.toString();
    }

    /**
     * 方法三：直接构造
     */
    public static String convert3(String str, int numRows){
        int n = str.length(),r = numRows;
        if(r == 1 || r > n) return str;
        int t = 2 * r - 2;
        StringBuffer ans = new StringBuffer();
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < n - i; j += t) {
                ans.append(str.charAt(j+i));
                if (0 < i && i < r -1 && j + t -i < n){
                    ans.append(str.charAt(j+t-i));
                }
            }
        }
        return ans.toString();
    }

    /**
     * 方法四：flag标志法
     */
    public static String convert4(String str, int numRows){
        if (numRows == 1 || numRows > str.length()){
            return str;
        }
        StringBuffer[] stringBuffers = new StringBuffer[numRows];
        for (int i = 0; i < stringBuffers.length; i++) {
            stringBuffers[i]=new StringBuffer();
        }
        int flag = -1;
        int i = 0;
        for (char c : str.toCharArray()) {
            stringBuffers[i].append(c);
            if (i == 0 || i == numRows -1){
                flag = -flag;
            }
            i += flag;
        }

        StringBuffer res = new StringBuffer();
        for (StringBuffer stringBuffer : stringBuffers) {
            res.append(stringBuffer);
        }
        return  res.toString();
    }


    public static int getRank(String str, int numRows){
        int num = str.length() / (numRows + numRows-2);
        int num1 = str.length() % numRows;
        int num2 = 0;
        if (num1 != 0){
            if (num1 <= numRows){
                num2 = 1;
            }else{
                num2 = num1- numRows +1;
            }
        }
        return num + num*(numRows-2) + num2;
    }

    /**
     *java做数学，化简与不化简结果不一样，因为java做除法的时候会向下取整；
     */
    public static void getNum(String s, int numRows){
        int n = s.length(),r=numRows;
        int t = r * 2 - 2;
        int c0 = n/2;
        int c1 = n/t * (r-1);
        int c2 = (n + t -1)/t*(r-1);
        int c3 = (n/2)+(r/2)-1;
        System.out.println(c0);
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);

    }
}
